package 泛型;

/*
【泛型继承】
一个类可以继承自一个泛型类。例如：父类的类型是Pair<Integer>，子类的类型是IntPair，可以这么继承：
public class IntPair extends Pair<Integer> {}
使用的时候，因为子类IntPair并没有泛型类型，所以，正常使用即可：IntPair ip = new IntPair(1, 2);
前面讲了，我们无法获取Pair<T>的T类型，即给定一个变量Pair<Integer> p，无法从p中获取到Integer类型。

但是，在父类是泛型类型的情况下，编译器就必须把类型T（对IntPair来说，也就是Integer类型）保存到子类的class文件中，
不然编译器就不知道IntPair只能存取Integer这种类型。

在继承了泛型类型的情况下，子类可以获取父类的泛型类型。例如：IntPair可以获取到父类的泛型类型Integer。获取父类的泛
型类型代码比较复杂：
*/
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

public class 泛型继承 {
	public static void main(String[] args) {
		Class<IntPair> clazz = IntPair.class;
		Type t = clazz.getGenericSuperclass();
		if (t instanceof ParameterizedType) {
			ParameterizedType pt = (ParameterizedType) t;
			Type[] types = pt.getActualTypeArguments(); // 可能有多个泛型类型
			Type firstType = types[0]; // 取第一个泛型类型
			Class<?> typeClass = (Class<?>) firstType;
			System.out.println(typeClass); // Integer
		}
	}
}

class Pair<T> {
	private T first;
	private T last;

	public Pair(T first, T last) {
		this.first = first;
		this.last = last;
	}

	public T getFirst() {
		return first;
	}

	public T getLast() {
		return last;
	}
}

class IntPair extends Pair<Integer> {
	public IntPair(Integer first, Integer last) {
		super(first, last);
	}
}

/*
因为Java引入了泛型，所以，只用Class来标识类型已经不够了。实际上，Java的类型系统结构如下：
                       ┌────┐
                       │Type│
                       └────┘
                         ▲
                         │
   ┌────────────┬────────┴─────────┬───────────────┐
   │            │                  │               │
┌─────┐┌─────────────────┐┌────────────────┐┌────────────┐
│Class││ParameterizedType││GenericArrayType││WildcardType│
└─────┘└─────────────────┘└────────────────┘└────────────┘
*/